package com.witframework.plugin.jbossrules.support;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.drools.FactHandle;
import org.drools.WorkingMemory;

import com.witframework.plugin.jbossrules.RuleBaseLoader;
import com.witframework.plugin.jbossrules.RuleBaseManager;
import com.witframework.plugin.jbossrules.RuleTemplate;


/**
 * 内置的RuleBase管理对象
 */
public class RuleTemplateImpl implements RuleTemplate {
	private static Logger logger = Logger.getLogger(RuleTemplateImpl.class);
	private Map globalObject=new HashMap();
	private RuleBaseManager ruleBaseManager = new RuleBaseManager();
	private WorkingMemory wm=null;
	public void setRuleBaseLoader(RuleBaseLoader ruleBaseLoader) {
		ruleBaseManager.setRuleBaseLoader(ruleBaseLoader);
		initWorkingMemory();
	}
	/**
	 * set global object
	 * @param global
	 */
	public void setGlobal(Map global){
		//Global 是一个能够被传进 WorkingMemory 但不需要 assert 的命名对象。
		//大多数这些对象被用来作为静态信息或服务。
		//这些服务被用在一条规则的 RHS ，或者可能是从规则引擎返回对象的一种方法。
		globalObject=global;
		for (Iterator iter = globalObject.keySet().iterator(); iter.hasNext();) {
			String key = (String) iter.next();
			wm.setGlobal(key, globalObject.get(key));
			logger.info("set global object:" + key);
		}
	}

	private WorkingMemory initWorkingMemory(){
		if(wm==null){
			wm = ruleBaseManager.getSession();
		}
		return wm;
	}
	private void assertObject(Object[] facts){
		for (int i=0;i<facts.length;i++){
			Object obj = facts[i];
			if (null == obj) {
				continue;
			}
			//添加调试侦听器
			//wm.addEventListener(new DebugWorkingMemoryEventListener());
			//这个 FactHandle 是一个代表在 Working Memory 中你的 asserted Object 的令牌（ token ）。
			//当你希望 retract 或者 modify 一个对象的时候，
			//这个令牌让你用来同 WorkingMemory 进行交互。
			FactHandle fact = wm.getFactHandle(obj);
			if (null == fact) {
				wm.insert(obj);//被检查是否匹配规则,将fact设置为动态（dynamic）模式
			} else {
				wm.update(fact, obj);
			}
		}
	}
	public Iterator executeRules(String groupName, Object[] facts) throws Exception{
		assertObject(facts);
		// 设置focus的规则组
		if (StringUtils.isNotEmpty(groupName)) {
			wm.setFocus(groupName);
		}
		// 规则结果的执行在调用 WorkingMemory 对象的 fireAllRules() 方法时执行
		wm.fireAllRules();
		return wm.iterateObjects();

		}

	public Iterator executeRules(Object[] facts) throws Exception{
		return executeRules(null, facts);
	}
	public Iterator executeRules(Object fact) throws Exception{
		return executeRules(null, new Object[]{fact});
	}
}
